package com.nx.platform.es.bean.modle.query;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ListMultimap;
import com.google.common.primitives.Floats;
import com.nx.platform.es.bean.dto.RequestContext;
import com.nx.platform.es.biz.wrapper.parser.StatementOperator;
import org.apache.commons.collections4.MapUtils;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.*;

import java.util.List;
import java.util.Objects;

/**
 * 实现 key=v or key2=v 类型查询。
 * buyer or seller = A
 * @author alex
 * @brief
 * @date 2019/11/20
 */
public class NumberMultiKeyHandler implements QueryFieldHandler {
    @Override
    public void handle(ImmutableMap<String, ?> fieldConfig, RequestContext context, String fieldFace,
                       StatementOperator operator, String fieldValue, ListMultimap<Boolean, QueryBuilder> queryBuilders) {


        //
        if (Strings.isNullOrEmpty(fieldValue)) {
            return;
        }
        // 记录Query信息(Trace)
        context.getTrace().append("&").append(fieldFace).append(operator.getSymbol()).append(fieldValue);
        //
        String face = MapUtils.getString(fieldConfig, "face");
        String fieldName = MapUtils.getString(fieldConfig, "fieldName");
        Object _fields = MapUtils.getObject(fieldConfig, "_fields");  //fieldName=A,B.  分割
        String _operator = MapUtils.getString(fieldConfig, "_operator");
        Preconditions.checkState(!Strings.isNullOrEmpty(fieldName));
        //判断fieldName是否合规
        Preconditions.checkState(_fields instanceof List, "param _fields incorrect");
        List<?> fields = List.class.cast(_fields);
        String[] fieldNames = fields.stream().filter(Objects::nonNull).map(String::valueOf).toArray(String[]::new);
        if (fieldNames.length == 0) {
            return;
        }
        //
        List<String> values = Splitter.on("|").omitEmptyStrings().splitToList(fieldValue);
        if (values.isEmpty()) {
            return;
        }
        if (values.size() > 8) {
            throw new IllegalArgumentException("too more alternatives: field=" + face + ", value=" + fieldValue);
        }

        //字段查询的条件是或，用一层query包裹
        BoolQueryBuilder bool = QueryBuilders.boolQuery();
        values.forEach(value -> bool.should(build(fieldNames, _operator, value)));
        bool.minimumShouldMatch("1");
        queryBuilders.put(operator.isSign(), bool);
    }

    private MultiMatchQueryBuilder build(String[] fieldNames, String _operator, String fieldValue) {
        MultiMatchQueryBuilder multiMatch = QueryBuilders.multiMatchQuery(fieldValue);
        for (String fieldName : fieldNames) {
            int index = fieldName.indexOf('^');
            if (index > 0) {
                String field = fieldName.substring(0, index);
                Float boost = Floats.tryParse(fieldName.substring(index + 1));
                multiMatch.field(field, boost == null ? 1.0f : boost);
            } else {
                multiMatch.field(fieldName);
            }
        }

        if ("and".equals(_operator)) {
            multiMatch.operator(Operator.AND);
        } else {
            multiMatch.operator(Operator.OR);
        }

        return multiMatch;
    }

}
